#include "Downloader.hpp"

#include <emscripten.h>
#include <emscripten/fetch.h>

#include "EyerWASMHttp/EyerWASMHttpHeader.hpp"

namespace Eyer {
    Downloader::Downloader(const std::string & _path)
    {
        path = _path;
    }

    Downloader::~Downloader()
    {
        if(buf != nullptr){
            free(buf);
            buf = nullptr;
        }
        bufLen = 0;
    }

    int Downloader::Open()
    {
        std::unique_lock<std::mutex> lock(mut);

        int ret = 0;

        if(bufLen > 0){
            return ret;
        }

        EyerWASMHttp wasmHttp(path.c_str());
        wasmHttp.Send();
        wasmHttp.WaitHttpBody();

        int httpCode = wasmHttp.GetHttpStatus();
        if(httpCode > 0){
            buf = (uint8_t *)malloc(wasmHttp.GetBufferLen());
            memcpy(buf, wasmHttp.GetBuffer(), wasmHttp.GetBufferLen());
            bufLen = wasmHttp.GetBufferLen();
        }
        else {
            buf = NULL;
            bufLen = 0;
            ret = -1;
        }
        /*
        emscripten_fetch_attr_t attr;
        emscripten_fetch_attr_init(&attr);
        strcpy(attr.requestMethod, "GET");
        attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS;
        emscripten_fetch_t * fetch = emscripten_fetch(&attr, path.c_str());
        if (fetch->status >= 200 && fetch->status < 300) {
            // printf("Finished xxx downloading %llu bytes from URL %s\n", fetch->numBytes, fetch->url);
            buf = (uint8_t *)malloc(fetch->numBytes);
            memcpy(buf, fetch->data, fetch->numBytes);
            bufLen = fetch->numBytes;
            ret = 0;
        } else {
            // printf("Fail downloading %s\n", fetch->url);
            buf = NULL;
            bufLen = 0;
            ret = -1;
        }
        emscripten_fetch_close(fetch);
        */

        return ret;
    }

    int Downloader::Read(uint8_t * targetBuf, int size, int pos)
    {
        std::unique_lock<std::mutex> lock(mut);
        if(bufLen <= 0){
            return -1;
        }

        int maxLen = bufLen - pos;

        if(maxLen <= 0){
            return -1;
        }

        int len = std::min(maxLen, size);

        memcpy(targetBuf, buf + pos, len);

        return len;
    }

    int Downloader::Close()
    {
        std::unique_lock<std::mutex> lock(mut);

        return 0;
    }
}